﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AllegroIWI.Comparers;

namespace AllegroIWI
{
	public class GroupUtility
	{
		public List<List<SearchResult>> Groups = null;

		public List<List<SearchResult>> doGrouping(List<SearchResult> SearchResults)
		{
			List<List<SearchResult>> Groups = new List<List<SearchResult>>();
			SamePictureComparer comparer = new SamePictureComparer();
			SearchResults.Sort(comparer);
			for (int i = 0; i < SearchResults.Count; i++)
			{
				List<SearchResult> group = new List<SearchResult>();
				group.Add(SearchResults[i]);
				while (i + 1 < SearchResults.Count - 1 && comparer.Compare(SearchResults[i], SearchResults[i + 1]) == 0)
				{
					bool test = comparer.Compare(SearchResults[i], SearchResults[i + 1]) == 0;
					group.Add(SearchResults[i + 1]);
					i++;
				}
				Groups.Add(group);
			}
			return Groups;
		}

		public List<List<SearchResult>> doChiSimiliarComparer(List<SearchResult> SearchResults, int accuracy)
		{
			return doSimilarGrouping(SearchResults, new SimiliarHistogramChiComparer(), accuracy);
		}
		public List<List<SearchResult>> doHammingSimiliarComparer(List<SearchResult> SearchResults, int accuracy)
		{
			return doSimilarGrouping(SearchResults, new SimilarHistogramComparer(), accuracy);
		}
		public List<List<SearchResult>> doSimilarGrouping(List<SearchResult> SearchResults, Comparer<SearchResult> histogramComparer, int accuracy)
		{
			List<List<SearchResult>> Groups = new List<List<SearchResult>>();

			SameNameComparer comparer = new SameNameComparer();
			SearchResults.Sort(comparer);
			List<SearchResult> CopySearchResults = new List<SearchResult>(SearchResults);
			for (int i = CopySearchResults.Count - 1; i >= 0; i = CopySearchResults.Count - 1)
			{
				List<SearchResult> group = new List<SearchResult>();
				List<int> toDel = new List<int>();
				group.Add(CopySearchResults[i]);
				toDel.Add(i);
				int diff = 0;
				for (int j = CopySearchResults.Count-2; j >= 0; j--)
				{
					diff = histogramComparer.Compare(CopySearchResults[i], CopySearchResults[j]);
					if (diff < accuracy)
					{
						group.Add(CopySearchResults[j]);
						toDel.Add(j);
					}
				}
				for (int k = 0; k < toDel.Count;k++)
					CopySearchResults.RemoveAt(toDel[k]);
				Groups.Add(group);
			}
			return Groups;
		}

		public void performGrouping(List<SearchResult> SearchResults, int accuracy)
		{
			List<List<SearchResult>> Groups = new List<List<SearchResult>>();
			List<List<SearchResult>> newGroups = null;
			int i;
			
			newGroups = doGrouping(SearchResults);
			newGroups.Sort(new GroupDescComparer());
			SearchResults = new List<SearchResult>();
			i = newGroups.Count - 1;
			while (i >= 0 && newGroups[i].Count == 1)
			{
				SearchResults.Add(newGroups[i][0]);
				newGroups.RemoveAt(i);
				i--;
			}
			Groups.AddRange(newGroups);

			newGroups = doHammingSimiliarComparer(SearchResults, accuracy);
			newGroups.Sort(new GroupDescComparer());
			SearchResults = new List<SearchResult>();
			i = newGroups.Count - 1;
			while (i >= 0 && newGroups[i].Count == 1)
			{
				SearchResults.Add(newGroups[i][0]);
				newGroups.RemoveAt(i);
				i--;
			}
			Groups.AddRange(newGroups);

			newGroups = doChiSimiliarComparer(SearchResults, accuracy);
			newGroups.Sort(new GroupDescComparer());
			SearchResults = new List<SearchResult>();
			i = newGroups.Count - 1;
			while (i >= 0 && newGroups[i].Count == 1)
			{
				SearchResults.Add(newGroups[i][0]);
				newGroups.RemoveAt(i);
				i--;
			}
			Groups.AddRange(newGroups);

			//newGroups = doTextSimiliarComparer(SearchResults);
			//newGroups.Sort(new GroupDescComparer());
			//SearchResults = new List<SearchResult>();
			//i = newGroups.Count - 1;
			//while (i >= 0 && newGroups[i].Count == 1)
			//{
			//    SearchResults.Add(newGroups[i][0]);
			//    newGroups.RemoveAt(i);
			//    i--;
			//}
			//Groups.AddRange(newGroups);

			this.Groups = Groups;
		}

	}
}
